加密与解密 第2篇 调试篇
第二章 动态分析技术
2.1 ollyDbg
2.1.1 ollyDbg界面
- 窗口
CPU等各窗口
-
CPU面板窗口
-
反汇编
-
address列
-
hex dump列
快捷键:F2设置断点
-
Disassemly列
-
comment
快捷键:;
-
多行选择
-
shift+键盘上下
- ctrl+鼠标
-
-
信息
- 与指令相关的寄存器值
- api调用提示
- 跳转提示
- 等
-
数据
- 十六进制显示文件在内存中的数据
-
寄存器
-
堆栈
2.1.2 OllyDbg的设置
界面设置
- udd文件和插件路径设置
options -> appearance-> Directores
设置成绝对路径
- udd文件
保存当前调试的一些状态
- 断点
-
注释等
-
插件
调试设置
Options -> Debugging options
忽略各种异常
加载符号文件
- 让ollydbg以函数名显示DLL中的函数
Debug->select import libraries
关联到右键
Options/add to explorer->Add ollydbg to menu...
2.1.3 加载程序
createProces创建进程
附加到一个运行的进程上
File/Attach
- 隐藏进程的附加
shell
ollydbg.exe -p pid值
-
附加不成功
-
a.exe 调用b.exe
- b.exe附加不成功
- 设置olldbg为
Just-in-time debugging
- 修改b.exe的入口点指令为CC(int 3)
- 运行a.exe
- b.exe运行到int 3异常
- 还原原指令,继续调试
2.1.4 基本操作
-
准备工作
-
加载目标文件调试
Options/Debugging Options -> Event
断点设置:
- system breakpoints: int3
- Entry point of main module:主模块的入口点
-
winMain: 即使设置了这个选项,一般也会断在文件入口点
-
断点跟踪
功能键 | 功能 |
---|---|
F7 | 单步步进 |
F8 | 单步步过 |
Ctrl+F9 | 直到出现Ret指令时中断 |
alt+F9 | 若进入系统领空,瞬间返回应用程序领空 |
F9 | 运行程序 |
ctlr+F2 | 重新调试应用程序 |
F12 | 暂停程序,程序进入死循环时可以使用 |
F2 | 设置/取消断点 |
alt+B | 打开断点窗口(不显示硬件断点) |
ctrl+N | 打开应用程序输入表 |
F3 | 打开文件 |
F5 | 显示各个窗口,双击返回当前窗口 |
ALT+M | 显示内存 |
F4 | 执行到光标所在行 |
shift+F2 | 条件断点 |
shift+F4 | 条件记录断点 |
Alt+F7 | 转到上一个找到的参考 |
Alt+F8 | 转到下一个找到参考 |
Ctrl+R | 搜索所选命令的参考。该命令扫描激活模块的全部可执行代码,以找到涉及到首个选中的命令的全部相关参考(包括:常量、跳转及调用),您可以在参考中使用快捷键 Alt+F7 和 Alt+F8来浏览这些参考。为便于您使用,被参考的命令也包含在该列表中。 |
-
需要多次按F7或者F8键时,可以按
ctrl+F7
或者ctlr+F8
,直到ESC、F12或者遇到其他断点中止 -
设置断点
-
在特定表达式上设置断点
- Ctrl+G : 打开跟随表达式窗口(e.g
GetDlgItemTextA
) - F2 设置断点
- win9x系统中,ollydbg无法对api函数设断点
- 在输入表中设置断点
- Ctrl+N 打开输入表
- 找到要找的函数
- enter或者右键"Find references to import"命令打开调用此函数的参考代码窗口,找到相应的代码
- enter切换到相应的代码
- F2设置断点
- Ctrl+G : 打开跟随表达式窗口(e.g
-
调试分析
-
程序中断后,
alt+f9
回到调用函数的地方 alt+b
,禁用掉getDlgItemTextA
断点- 为了方便反复调试,在调用出设置断点
代码阅读
-
API定义
-
调用约定
- __stdcall
- 参数从右向左顺序入栈
- 由被调用者清理堆栈中的参数
- 返回值保存在eax中
- C调用
- 参数从右向左顺序入栈
- 由调用者清理堆栈参数
- __stdcall
-
查看指定地址处内存值的变化
e.g
push eax
- 在当前代码行暂停
- 在
eax
寄存器窗口上右键,执行"Follow Dump",查看数据窗口 - 单步执行
call GetDlgItemTextA
完成 - 已经看到内存中值的变化
-
保存修改后的文件
e.g : je short 0040122E
- 修改
ZF
标志位,单击取反 - 修改改行代码为
9090
- 鼠标右键,
copy to executable/Selection
-
save File
-
算法分析
2.1.5 断点
-
int 3断点
-
原理:其机器码是CCh,也常称为CC指令,当被调试进程执行INT3指令导致一个异常时,调试器会捕捉这个异常从而停在断点处,然后将该断点处的指令恢复成原来指令
Ø 优点:可以设置无数个断点
Ø 缺点:改变了原程序指令,容易被软件检测到
Ø 设置方法:F2设置(就是普通的断点) F2取消
-
硬件断点
-
原理:硬件断点和DRx调试寄存器有关,DRx有8个寄存器
DR0~3:调试地址寄存器,保存需要监视的地址,如设置硬件断点
DR4~5:保留
DR6:调试寄存器组状态寄存器
DR7:调试寄存器组控制寄存器
硬件断点是使用DR0 DR1 DR2 DR3来设置断点
Ø 优点:断点速度快,不容易被发现
Ø 缺点:只能设置4个断点DR0 DR1 DR2 DR3
Ø 设置方法:F8到需要设置的位置,右键“Breakpoint/Hardware,on execution”
- 内存断点
Ø 原理:OD可以设置内存访问断点或内存写入断点,原理是对所设的地址设为不可访问/不可写属性,同样当访问/写入的时候会报异常,并且停留在异常处
Ø 优点:内存断点不修改原代码。它不像INT3断点,因为修改程序代码而导致中断,因此在遇到代码校验,并且硬件断点失灵情况下,可以用内存断点来代替
Ø 缺点:只能设置1次
Ø 设置方法:
右键->Breakpoint->Memory ,on access(断点/内存写入)
->Memory ,on write(断点/内存访问)
- 内存访问一次性断点
Ø 原理:原理和”Set memory breakpoint on access”功能一样
Ø 优点:对整个内存块设置断点,快捷键也是F2
Ø 特点:一次性断点,当所在段读取或执行时就中断,中断发生以后,断点将被删除
Ø 设置方法:ALT+M 右键->”Set break-on-access”
-
消息断点
-
原理:Windows本身是由消息驱动的,如果调试时没有合适的断点,额可以尝试消息断点
-
如何中断返回
- 在中断后,由于处在系统代码底层,所以
alt+F9
或者ctrl+F9
,无法回到程序的代码领空 - 所以,需要在.txt段中设置内存访问断点
set break-on-access
- F9运行
- 由于中断的地方可能不是想要的消息,所以,可能需要重复1-3步数次,最后发现check按钮事件代码
- alt+b进入断点窗口,删除消息断点
- 在中断后,由于处在系统代码底层,所以
-
条件断点
-
条件记录断点
2.1.6 插件
-
常用插件
-
command bar
alt +F1
快速显示/隐藏command barcltr+D
快速定位到输入框 -
插件开发
2.1.7 run trace
2.1.8 hit trace
2.1.9 符号调试技术
-
符号格式
-
将16进制数转换为源文件代码行、函数名以及变量名称
-
创建调试文件
以vc6.0为例,建立带有pdb调试信息的调试版本:
- bulild -> set active configuration -> win32 debug
- project -> settings -> c/c++ -> category -> general -> debug info -> program database 产生pdb文件
-
link -> category -> debug -> debug info & microsoft format & separate types & generate mapfiles 产生map文件
-
用符号文件调试
-
debugging options -> cpu -> synchronize soure with cpu 选中
- cpu窗口-> 单击comment栏 -> 切换到source
- debugging options -> debug -> hide none-existing source files 取消选中
- view/source files 选中正确的源文件
- view/source 打开源代码窗口,就可以看到源码
- 在源码窗口下断点,F9运行,就可以正常在源码和反汇编窗口同步调试应用程序了
2.1.10 OllyDbg常见问题
-
乱码的问题
-
如何快速回到当前领空
双击寄存器窗口的EIP
- Ollydbg如何修改EIP
Ctlr+*
发现笔记本键盘无效:cry:
- 什么是UDD
所有程序或模组相关的信息
- 删除了断点,重新加载时,会重新出现
ollydbg.ini -> 修改为 bacup UDD files=1
push E000
未知字符
0E000 -> 0E000
- 假死
ollydbg.ini -> restore windows=0
- 微调窗口显示
ctrl+↑ 或者 ctrl+↓ 上下翻动一个字节
- “复制到可执行文件”-> 报错:“Unable to locate data in executable file”
修改的地方不在raw size范围内,修改pe文件,是rawSize=VirtualSize
-
能否把call调用修改为函数名称形式
shift+;
-> 输入函数名称